#include <iostream>
using std::cout;
using std::endl;

class Base
{
public:
    Base(long base)
    : _base(base)
    {   cout << "Base(long)" << endl;   }

    virtual
    void print() const 
    {   cout << "Base::_base:" << _base << endl;    }

private:
    long _base;
};

class Derived
: public Base
{
public:
    Derived(long base, long derived)
    : Base(base)
    , _derived(derived)
    {   cout << "Derived(long,long)" << endl;   }

    void display() const
    {   cout << "Derived::_derived: " << _derived << endl;  }

private:
    long _derived;
};

void test0()
{
    Base base(1);
    base.print();

    Derived derived(10, 100);

    //Base(const Base &rhs);
    Base base2 = derived;
    cout << "bas2.print():";
    base2.print();

    //完成了赋值操作
    cout << "执行 base = derived;" << endl;
    //Base & operator=(const Base& rhs)
    //可以将一个基类引用绑定到派生类对象
    //const Base & rhs = derived;
    //可以将一个派生类对象赋值给基类对象
    base = derived;//ok

    base.print();

}

void test1()
{
    Base base(1);
    base.print();

    Derived derived(10, 100);

    //Derived & operator=(const Derived&rhs);
    //const Derived & rhs = base;
    //derived = base;//error

}

void test2()
{
    Base base(1);
    base.print();

    Derived derived(10, 100);
    Base * pbase = &base;
    pbase->print();

    Derived * pderived = &derived;
    pderived->display();

    //当派生类指针指向基类对象时，如果能正常执行
    //通过派生类指针可以操作一块不属于Base对象的空间
    //这是一个不确定的情况
    //pderived = &base;//error
    //pderived->display();
    
    //因为derived对象的空间包含了基类的空间，
    //当用基类指针指向派生类对象时，只需要操作
    //基类部分就可以了
    pbase = &derived;
    pbase->print();

}

void test3()
{
    Base base(1);
    base.print();

    Derived derived(10, 100);
    //pbase指向的就是一个基类对象
    Base * pbase = &base;
    pbase->print();

    Derived * pderived = &derived;
    pderived->display();

    cout << "000" << endl;
    //pderived2不能指向pbase
    Derived * pderived2 = (Derived*)pbase;//error
    pderived2->display();


    //pbase指向的就是一个派生类对象
    pbase = &derived;
    pbase->print();

    cout << "111" << endl;
    //pderived3可以指向pbase的
    Derived * pderived3 = (Derived*)pbase;
    pderived3->display();
}

void test4()
{
    Base base(1);
    base.print();

    Derived derived(10, 100);
    //pbase指向的就是一个基类对象
    Base * pbase = &base;
    pbase->print();

    Derived * pderived = &derived;
    pderived->display();

    cout << "000" << endl;
    //pderived2不能指向pbase
    Derived * pderived2 = dynamic_cast<Derived*>(pbase);//ok
    if(pderived2){
        cout << "转换成功" << endl;
        pderived2->display();
    } else {
        cout << "转换失败" << endl;
    }


    //pbase指向的就是一个派生类对象
    pbase = &derived;
    pbase->print();

    cout << "111" << endl;
    //pderived3可以指向pbase的
    Derived * pderived3 = dynamic_cast<Derived*>(pbase);
    if(pderived3) {
        cout << "转换成功" << endl;
        pderived3->display();
    } else {
        cout << "转换失败" << endl;
    }
}
int main()
{
    /* test0(); */
    /* test1(); */
    /* test2(); */
    /* test3(); */
    test4();
    return 0;
}

